package emulator.unittest.hardware.io;


import static org.junit.Assert.*;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import emulator.hardware.bits.SharedBit;
import emulator.hardware.io.Port6522;

public class Port6522Test {

	SharedBit[] in_port_bit = new SharedBit[Port6522.NUM_PORT_BITS];
	SharedBit[] out_port_bit = new SharedBit[Port6522.NUM_PORT_BITS];
	SharedBit[] control_bit = new SharedBit[Port6522.NUM_CONTROL_BITS];
	Port6522 port = new Port6522();
	
	@Before
	public void setUp() throws Exception {
		for (int i = 0; i < Port6522.NUM_PORT_BITS; i++)
		{
			in_port_bit[i] = port.getInPortBit(i);
			out_port_bit[i] = port.getOutPortBit(i);
		}
		for (int i = 0; i < Port6522.NUM_CONTROL_BITS; i++)
			control_bit[i] = port.getControlBit(i);
		
		resetBits();
	}

	private void resetBits() {
		SharedBit.setBits(in_port_bit, 0);
		SharedBit.setBits(out_port_bit, 0);
		SharedBit.setBits(control_bit, 0);
	}

	@After
	public void tearDown() throws Exception {
	}

	@Test
	public void testInitPortBits()
	{
		for (int i = 0; i < Port6522.NUM_PORT_BITS; i++)
		{
			assertNotNull(in_port_bit[i]);
			assertNotNull(out_port_bit[i]);
		}
	}
	
	@Test
	public void testInitControlBits()
	{
		for (int i = 0; i < Port6522.NUM_CONTROL_BITS; i++)
			assertNotNull(control_bit[i]);
	}
	
	@Test
	public void testSetGetMask()
	{
		port.setPortMask(0x0f);
		assertEquals(0x0f, port.getPortMask());
		port.setPortMask(0xf0);
		assertEquals(0xf0, port.getPortMask());
	}
	
	@Test
	public void testWritePort()
	{
		port.setPortMask(0xff);
		port.writePort(0x55);
		assertEquals(0x55, SharedBit.getBits(out_port_bit));
		port.writePort(0xaa);
		assertEquals(0xaa, SharedBit.getBits(out_port_bit));
	}

	@Test
	public void testWritePortMasked()
	{
		port.setPortMask(0x55);
		port.writePort(0xf0);
		assertEquals(0x50, SharedBit.getBits(out_port_bit));
		resetBits();
		port.setPortMask(0xaa);
		port.writePort(0x0f);
		assertEquals(0x0a, SharedBit.getBits(out_port_bit));
	}

	@Test
	public void testWritePortMaskedUntouched()
	{
		port.setPortMask(0x55);
		out_port_bit[1].setValue(true);
		port.writePort(0xf0);
		assertEquals(0x52, SharedBit.getBits(out_port_bit));
		port.setPortMask(0xaa);
		port.writePort(0x0f);
		assertEquals(0x5a, SharedBit.getBits(out_port_bit));
	}
	
	@Test
	public void testReadPort()
	{
		SharedBit.setBits(in_port_bit, 0x55);
		assertEquals(0x55, port.readPort());
		SharedBit.setBits(in_port_bit, 0xaa);
		assertEquals(0xaa, port.readPort());
	}
}
